package com.coder.rental.controller;

import cn.hutool.core.convert.NumberWithFormat;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.StrUtil;
import cn.hutool.jwt.JWTPayload;
import com.coder.rental.entity.Permission;
import com.coder.rental.entity.User;
import com.coder.rental.service.IUserService;
import com.coder.rental.utils.JwtUtils;
import com.coder.rental.utils.RedisUtils;
import com.coder.rental.utils.Result;
import com.coder.rental.utils.RouteTreeUtils;
import com.coder.rental.vo.RouteVo;
import com.coder.rental.vo.TokenVo;
import com.coder.rental.vo.UserInfoVo;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@RestController
@RequestMapping("/rental/auth/")
public class AuthController {
    @Resource
    private RedisUtils redisUtils;
    @Resource
    private IUserService iUserService;
    @PostMapping("/refreshToken")
    public Result refreshToken(HttpServletRequest request){
        //获取token
        String token=request.getHeader("token");
        if(StrUtil.isEmpty(token)){
            token=request.getParameter("token");
        }
        //生成新的token
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        UserDetails userDetails= (UserDetails) authentication.getPrincipal();
        String username=JwtUtils.parseToken( token).getClaim("username").toString();
        String newToken="";
        if(StrUtil.equals(username,userDetails.getUsername())){
            Map<String,Object> map=new HashMap<>();
            map.put("username",userDetails.getUsername());
            newToken=JwtUtils.createToken(map);
        }
        //获取过期时间
        NumberWithFormat claim= (NumberWithFormat) JwtUtils.parseToken(newToken).getClaim(JWTPayload.EXPIRES_AT);
        DateTime dateTime= (DateTime) claim.convert(DateTime.class,claim);
        long expireTime=dateTime.getTime();
        //将新token和过期时间存入Vo对象
        TokenVo tokenVo=new TokenVo();
        tokenVo.setToken(newToken);
        tokenVo.setExpireTime(expireTime);
        //删除旧token
        redisUtils.del("token"+token);
        //将新token存入Redis
        long nowTime= DateTime.now().getTime();
        String newTokenKey="token:"+newToken;
        redisUtils.set(newTokenKey,newToken,(expireTime-nowTime)/1000);
        return Result.success(tokenVo).setMessage("刷新Token成功");
    }
    /**
     * 获取当前登录用户的信息
     *
     * @return Result 包含用户信息的统一返回结果，用户信息包含用户ID、用户名、头像、昵称和角色列表
     */
    @GetMapping("/getInfo")
    public Result getUserInfo(){
        // 获取当前认证信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if(authentication==null){
            return Result.fail().setMessage("用户未登录");
        }
        // 获取用户主体信息并转换为User对象
        User user= (User) authentication.getPrincipal();
        // 查询用户角色名称列表
        List<Permission> permissionList = user.getPermissionList();
        Object[] array = permissionList.stream().filter(Objects::nonNull)
                .map(Permission::getPermissionCode)
                .toArray();
        // 构造用户信息VO对象
        UserInfoVo userInfoVo=new UserInfoVo(user.getId(), user.getUsername(),
                user.getAvatar(), user.getNickname(), array);
        return Result.success(userInfoVo).setMessage("获取用户信息成功");
    }
    @GetMapping("/menuList")
    public Result getMenuList(){
        // 获取当前认证信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if(authentication==null){
            return Result.fail().setMessage("用户未登录");
        }
        // 获取用户主体信息并转换为User对象
        User user= (User) authentication.getPrincipal();
        List<Permission> permissionList=user.getPermissionList();
        permissionList.removeIf(permission -> Objects.equals(permission.getPermissionType(),2));
        List<RouteVo> routeVoList = RouteTreeUtils.buildRouteTree(permissionList, 0);
        return Result.success(routeVoList).setMessage("获取菜单列表成功");
    }
    @PostMapping("/logout")
    public Result logout(HttpServletRequest request, HttpServletResponse response){
        String token=request.getHeader("token");
        if(StrUtil.isEmpty(token)){
            token=request.getParameter("token");
        }
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if(authentication!=null){
            redisUtils.del("token:"+token);
            SecurityContextLogoutHandler handler=new SecurityContextLogoutHandler();
            handler.logout(request,response,authentication);
            return Result.success().setMessage("退出登录成功");
        }
        return Result.fail().setMessage("登陆失败!");
    }

}
